package cn.ycl.system.other.config.scheduler.sendmsgscheduler;

import org.springframework.boot.autoconfigure.batch.BatchProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import java.lang.reflect.Method;
import java.util.concurrent.Executors;

/**
 * @author YuanChangLiang
 */
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        Method[] methods = BatchProperties.Job.class.getMethods();
        int defaultPoolSize = 3;
        int corePoolSize = 0;
        if (methods.length > 0) {
            for (Method method : methods) {
                Scheduled annotation = method.getAnnotation(Scheduled.class);
                if (annotation != null) {
                    corePoolSize++;
                }
            }
            if (defaultPoolSize > corePoolSize) {
                corePoolSize = defaultPoolSize;
            }
        }

        /*
          @corePoolSize    核心池大小，除非设置了 allowCoreThreadTimeOut
                           否则哪怕线程超过空闲时间，池中也要最少要保留这个数目的线程。
          @maximumPoolSize 允许的最大线程数
          @keepAliveTime   空闲线程空闲存活时间，核心线程需要 allowCoreThreadTimeOut
                           为true才会退出。
          @unit            与 keepAliveTime 配合，设置 keepAliveTime 的单位，如：毫秒、秒。
          @workQueue       线程池中的任务队列。上面提到线程池的主要作用是复用线程来处理任务，
                           所以我们需要一个队列来存放需要执行的任务，在使用池中的线程来处理这些任务，
                           所以我们需要一个任务队列。
          @threadFactory   当线程池判断需要新的线程时通过线程工程创建线程。
         */
        taskRegistrar.setScheduler(Executors.newScheduledThreadPool(corePoolSize));
        //new ThreadPoolExecutor(1, 5,
        //                60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1))

    }
}